home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / lisp / eulisp / you-075a.lha / you-075a / copyalloc.c < prev    next >
C/C++ Source or Header  |  1992-10-27  |  19KB  |  837 lines

  1.  /*    
  2.   * Allocation routines for feel
  3.   *
  4.   */
  5.  
  6. /* what we need to stay ahead*/
  7. #include "defs.h"
  8. #include "structs.h"
  9. #include "funcalls.h"
  10. #include "global.h"
  11. #include "allocate.h" 
  12. #include "error.h"
  13. #include "table.h"
  14.  
  15. /* other junk */
  16. #include "copy.h"
  17.  
  18. #ifndef DEFAULT_HEAP_SIZE
  19. #define DEFAULT_HEAP_SIZE (4*1024*1024)
  20. #endif
  21.  
  22. #ifndef DEFAULT_STACK_SPACE_SIZE
  23. #define DEFAULT_STACK_SPACE_SIZE (1*1024*1024)
  24. #endif
  25.  
  26. #define N_SLOTS_IN_CLASS N_SLOTS_IN_STRUCT(struct class_structure)
  27. #define N_SLOTS_IN_THREAD N_SLOTS_IN_STRUCT(struct thread_structure)
  28.  
  29. #define ROUNDTO 8
  30. #define ROUND_ADDR(x) ((((int)x)&(ROUNDTO-1))==0 ? x : x+(ROUNDTO-((int)x&(ROUNDTO-1))))
  31.  
  32. #ifdef NODEBUG
  33. #define FPRINTF_GC_BUG(x) 
  34. #define GC_BUG(x)
  35. #else
  36. #define GC_BUG(x) x
  37. #define FPRINTF_GC_BUG(x) fprintf x
  38. #endif
  39.  
  40. LispObject static_ints;
  41.  
  42. void runtime_initialise_allocator(LispObject *stacktop)
  43. {
  44.   static void initialise_stack_space(int);
  45.   extern void init_allocator(int);
  46.   extern int command_line_heap_size;
  47.   extern int command_line_stack_space_size;
  48.   extern int command_line_cons_percentage;
  49.   extern int command_line_cons_cut_off;
  50.  
  51.   int heap,stack_space;
  52.   
  53.   heap = (command_line_heap_size == 0
  54.             ? DEFAULT_HEAP_SIZE 
  55.             : command_line_heap_size);
  56.  
  57.   if (heap < 50)
  58.     heap=heap*1024*1024;
  59.  
  60.  
  61.   {
  62.     extern int command_line_cons_percentage;
  63.     extern int command_line_cons_cut_off;
  64.     
  65.     if (command_line_stack_space_size < 50)
  66.       command_line_stack_space_size = command_line_stack_space_size*1024*1024;
  67.  
  68.     stack_space = (command_line_stack_space_size == 0
  69.            ? DEFAULT_STACK_SPACE_SIZE
  70.            : command_line_stack_space_size);
  71.   }
  72.  
  73.   init_allocator(heap); 
  74.   initialise_stack_space(stack_space); 
  75.  
  76.   /* Really need a smarter way of doing these... --- like do them last */
  77.   add_root((LispObject *) &state_dynamic_env);
  78.   add_root(&state_last_continue);
  79.   add_root(&state_handler_stack);
  80.   add_root(&state_current_thread);
  81. }
  82.  
  83. char *allocate_space(LispObject *stacktop,int n)
  84. {
  85.   char* allocate_stack(LispObject *stacktop, int nbytes);  
  86.  
  87.   return allocate_stack(stacktop,n);
  88. }
  89.  
  90. void deallocate_space(LispObject*stacktop,char *addr,int siz)
  91. {
  92.   void deallocate_stack(LispObject *, char *, int);
  93.  
  94.   deallocate_stack(stacktop,addr,siz);
  95. }
  96. void runtime_initialise_collector(LispObject *stacktop)
  97. {
  98.  
  99. }
  100.  
  101. #define NOT_YET_DONE(name) \
  102. { fprintf(stderr,"%s: cannot alloc\n",name) ; return nil;}
  103.   
  104. LispObject Fn_cons(LispObject *stacktop)
  105. {
  106.   LispObject ans;
  107.  
  108.   ans = allocate_nbytes(stacktop+2,sizeof(struct cons_structure),TYPE_CONS); 
  109.   
  110.   lval_classof(ans)=Cons;
  111.   ans->CONS.car= *stacktop;
  112.   ans->CONS.cdr= *(stacktop+1);
  113.   
  114.   return ans;
  115. }
  116.  
  117. /* Optimised to allow easier code in a lot of places... */
  118. LispObject allocate_n_conses(LispObject *stacktop, int n)
  119. {    
  120.   LispObject xx;
  121.   int i;
  122. #ifdef NOWAY  
  123.   struct cons_structure *ptr;
  124.  
  125.   xx=allocate_cbytes(stacktop,n,sizeof(struct cons_structure),TYPE_CONS);
  126.   ptr= &(xx->CONS);
  127.   lval_classof(xx)=Cons;
  128.   ptr++;
  129.   for (i=1; i<n; i++)
  130.     {
  131.       ptr->header.class=Cons; /* XXX */
  132.       ptr->car=nil;    
  133.       (ptr[-1]).cdr=(LispObject)ptr;
  134.       ptr++;
  135.     }
  136.   
  137.   ptr[-1].cdr=nil;
  138.   return xx;
  139. #else
  140.   xx=nil;
  141.   for (i=0; i<n; i++)
  142.     {
  143.       xx=EUCALL_2(Fn_cons,nil,xx);
  144.     }
  145.       
  146.   return xx;
  147.  
  148. #endif
  149. }
  150.  
  151. LispObject allocate_n_envs(LispObject *stacktop, int n)
  152. {    
  153.   LispObject xx;
  154.   int i;
  155.   xx=0;
  156.   for (i=0; i< n; i++)
  157.     {
  158.       xx=allocate_env(stacktop,nil,nil,xx);
  159.     }
  160.  
  161.   return xx;
  162. }
  163.  
  164. LispObject allocate_class(LispObject *stacktop,LispObject class)
  165. {
  166.   LispObject ans;
  167.   int i;
  168.  
  169.   STACK_TMP(class);
  170.   if (class==NULL)
  171.     ans = allocate_nbytes(stacktop,sizeof(struct class_structure),TYPE_CLASS);
  172.   else 
  173.     ans = allocate_nbytes(stacktop,
  174.               sizeof(Object_t)+sizeof(LispObject)*class->CLASS.local_count,
  175.               TYPE_CLASS);
  176.   UNSTACK_TMP(class);
  177.   lval_classof(ans) = class;
  178.  
  179.   (ans->CLASS).name = unbound;
  180.   (ans->CLASS).superclasses = nil;
  181.   (ans->CLASS).subclasses = nil;
  182.   (ans->CLASS).slot_table = nil;
  183.   (ans->CLASS).slot_list = nil;
  184.   (ans->CLASS).direct_slot_list = nil;
  185.   (ans->CLASS).precedence = nil;
  186.   (ans->CLASS).local_count = 0;
  187.   
  188.   if (class!=NULL)
  189.     {
  190.       for (i=N_SLOTS_IN_CLASS ; i<class->CLASS.local_count ; i++)
  191.     slotref(ans,i) = nil;
  192.     }
  193.   return ans;
  194. }
  195.  
  196. LispObject allocate_instance(LispObject *stacktop,LispObject class)
  197. {
  198.   LispObject ans;
  199.   int i;
  200.  
  201.   STACK_TMP(class);
  202.  
  203.   ans=allocate_nbytes(stacktop,sizeof(Object_t)
  204.               +sizeof(LispObject)*class->CLASS.local_count,TYPE_INSTANCE);
  205.   UNSTACK_TMP(class);
  206.   lval_classof(ans)=class;
  207.  
  208.   for (i=0; i<class->CLASS.local_count; i++)
  209.     slotref(ans,i)=nil;
  210.  
  211.   return ans;
  212. }
  213.  
  214. LispObject allocate_thread(LispObject *stacktop,int stack_size, 
  215.                int gc_stack_size, int nslots)
  216.   char* allocate_stack(LispObject *stacktop, int nbytes);
  217.   /* xxx: need extra slots hack */
  218.   LispObject ans,cont;
  219.   int extra;
  220.  
  221.   extra=nslots>0? nslots-N_SLOTS_IN_THREAD: 0;
  222.   cont=allocate_continue(stacktop);
  223.   *stacktop=cont;
  224.   
  225.   
  226.   ans=allocate_nbytes(stacktop+1,
  227.               sizeof(struct thread_structure)+extra*sizeof(LispObject),
  228.               TYPE_THREAD);
  229.   cont = *stacktop;
  230.   *stacktop=ans;
  231.   lval_classof(ans) = Thread;
  232.  
  233.   (ans->THREAD).stack_size = stack_size;
  234.   (ans->THREAD).gc_stack_size = gc_stack_size;
  235.  
  236.   (ans->THREAD).fun = nil;
  237.   (ans->THREAD).args = nil;
  238.   (ans->THREAD).value = nil;
  239.  
  240.   (ans->THREAD).status = 0;
  241.  
  242.   (ans->THREAD).parent = nil;
  243.   (ans->THREAD).cochain = nil;
  244.   
  245.   (ans->THREAD).state = cont;
  246.   (ans->THREAD).stack_base = NULL;
  247.   (ans->THREAD).gc_stack_base = NULL;
  248.  
  249.   ans->THREAD.state->CONTINUE.thread=ans;
  250.  
  251. #ifdef MACHINE_ANY
  252.  
  253.   (ans->THREAD).stack_base = (int *) allocate_stack(stacktop+1,stack_size);
  254.   (ans->THREAD.state)->CONTINUE.gc_stack_pointer =
  255.     (ans->THREAD).gc_stack_base =
  256.       (LispObject *) allocate_stack(stacktop+1,gc_stack_size*sizeof(LispObject));
  257.   
  258.   fprintf(stderr,"{New stack: 0x%x->0x%x}", (ans->THREAD).gc_stack_base,
  259.        (ans->THREAD).gc_stack_base+gc_stack_size);
  260.   STACK_TMP(ans);
  261.   cont=EUCALL_2(Fn_cons,function_default_handler,nil);
  262.   UNSTACK_TMP(ans);
  263.   ans->THREAD.state->CONTINUE.handler_stack = cont;
  264.     
  265. #else
  266.  
  267.   ans->THREAD.stack_base = NULL;
  268.   ans->THREAD.gc_stack_base = NULL;
  269.   ans->THREAD.state->CONTINUE.gc_stack_pointer = NULL;
  270.   cont =  EUCALL_2(Fn_cons,function_default_handler,nil);
  271.  
  272.   ans->THREAD.state->CONTINUE.handler_stack = cont;
  273.  
  274.  
  275. #endif
  276.   { /* ugh */
  277.     int i;
  278.     if (extra>0)
  279.       for(i=N_SLOTS_IN_THREAD; i<nslots; i++)
  280.     slotref(ans,i) = unbound;
  281.   }
  282.   return ans;
  283. }
  284.  
  285. LispObject allocate_vector(LispObject *stacktop,int size)
  286. {
  287.   LispObject ans;
  288.   int i;
  289.  
  290.   ans = allocate_nbytes(stacktop,sizeof(Object_t)+sizeof(int)+size*sizeof(LispObject),
  291.             TYPE_VECTOR);
  292.   
  293.   lval_classof(ans)= Vector;
  294.   
  295.   ans->VECTOR.length=size;
  296.  
  297.   for(i=0; i<size ; i++)
  298.     vref(ans,i)=nil;
  299.  
  300.   return ans;
  301. }
  302.  
  303. LispObject allocate_string(LispObject *stacktop, char *string, int len)
  304. {
  305.   LispObject ans;
  306.  
  307.   len++;
  308.   len=ROUND_ADDR(len);
  309.   ans = allocate_nbytes(stacktop,sizeof(Object_t)+sizeof(int)+len,
  310.             TYPE_STRING); 
  311.   
  312.   lval_classof(ans)=String;
  313.   ans->STRING.length= len;
  314.   stringof(ans)[len-1]=0;
  315.   strncpy(stringof(ans),string,len);
  316.  
  317.   return ans;
  318. }
  319.  
  320. LispObject allocate_symbol(LispObject *stacktop, char *str)
  321. {
  322.   int hash(char *); /* from tables.c */
  323.  
  324.   int hv;
  325.   LispObject ans;
  326.   LispObject tmp,tmp2;
  327.   
  328.   tmp=allocate_string(stacktop,str,strlen(str));
  329.   STACK_TMP(tmp);
  330.   hv=hash(str);
  331.   tmp2=allocate_integer(stacktop,hv);
  332.   STACK_TMP(tmp2);
  333.   ans=allocate_nbytes(stacktop,sizeof(struct symbol_structure),TYPE_SYMBOL);
  334.   UNSTACK_TMP(tmp2);
  335.   UNSTACK_TMP(tmp);
  336.  
  337.   lval_classof(ans)=Symbol;
  338.   ans->SYMBOL.lvalue = nil;
  339.   ans->SYMBOL.lmodule = nil;
  340.   ans->SYMBOL.gvalue = NULL;
  341.   ans->SYMBOL.left = NULL;
  342.   ans->SYMBOL.right = NULL;
  343.   ans->SYMBOL.plist = nil;
  344.   ans->SYMBOL.hash = hv;
  345.   ans->SYMBOL.lhash = tmp2;
  346.   ans->SYMBOL.pname= tmp;
  347.  
  348.   return ans;
  349. }
  350.  
  351. LispObject allocate_table(LispObject *stacktop, LispObject (*comp)(LispObject*))
  352. {
  353.   LispObject ans;
  354.  
  355.   ans=allocate_nbytes(stacktop,sizeof(struct table_structure),TYPE_TABLE);
  356.   
  357.   lval_classof(ans)=Table;
  358.   (ans->TABLE).comparator = comp;
  359.   (ans->TABLE).lisp_comparator = nil;
  360.   (ans->TABLE).tree = nil;
  361.  
  362.   return ans;
  363. }
  364.  
  365. LispObject allocate_module_function(LispObject *stacktop,
  366.                     LispObject mod,LispObject name,
  367.                     LispObject (*fun)(LispObject*),
  368.                     int code)
  369. {
  370.   LispObject ans;
  371.  
  372.   STACK_TMP(name); STACK_TMP(mod);
  373.   ans=allocate_nbytes(stacktop,sizeof(struct c_function_structure),TYPE_C_FUNCTION);
  374.   UNSTACK_TMP(mod); UNSTACK_TMP(name);
  375.   lval_classof(ans) = Function;
  376.  
  377.   ans->C_FUNCTION.name = name;
  378.   ans->C_FUNCTION.home = mod;
  379.   ans->C_FUNCTION.argtype = code;
  380.   ans->C_FUNCTION.env = NULL;
  381.  
  382.   ans->C_FUNCTION.func = fun;
  383.   
  384.   return ans;
  385. }
  386.  
  387. #ifdef NOLOWTAGINTS
  388. LispObject real_allocate_integer(LispObject *stacktop, int n)
  389. {
  390.   LispObject ans;
  391.  
  392.   if (n>=0 && n<STATIC_INTEGERS)
  393.     return vref(static_ints,n);
  394.  
  395.   ans=allocate_nbytes(stacktop,sizeof(struct integer_structure),TYPE_INT);
  396.  
  397.   lval_classof(ans)=Integer;
  398.   intval(ans)=n;
  399.  
  400.   return ans;
  401. }
  402. #endif
  403.  
  404. /* stubs to keep arith.c happy */
  405. LispObject allocate_ratio(LispObject *stacktop,LispObject m,LispObject n)
  406. {
  407.   NOT_YET_DONE("ratio");
  408. }
  409.  
  410. LispObject allocate_complex(LispObject *stacktop,LispObject m,LispObject n)
  411. {
  412.   NOT_YET_DONE("complex");
  413. }
  414.  
  415. LispObject allocate_float(LispObject *stacktop,double x)
  416. {
  417.   LispObject ans;
  418.  
  419.   ans=allocate_nbytes(stacktop,sizeof(struct float_structure),TYPE_FLOAT);
  420.  
  421.   lval_classof(ans)=Real;
  422.   ans->FLOAT.fvalue=x;
  423.   
  424.   return ans;
  425.   
  426. }
  427.  
  428. LispObject allocate_char(LispObject *stacktop, char x)
  429. {
  430.   LispObject ans;
  431.  
  432.   ans=allocate_nbytes(stacktop,sizeof(struct character_structure),
  433.               TYPE_CHAR);
  434.   lval_classof(ans)=Character;
  435.   ans->CHAR.font=0;
  436.   ans->CHAR.code=x;
  437.   return ans;
  438.   
  439. }
  440.  
  441. LispObject allocate_continue(LispObject *stacktop)
  442. {
  443.  
  444.   LispObject ans;
  445.  
  446.   ans=allocate_nbytes(stacktop,sizeof(struct continue_structure),TYPE_CONTINUE);
  447.  
  448.   lval_classof(ans) = Continue;
  449.  
  450.   (ans->CONTINUE).thread = nil;
  451.  
  452.   (ans->CONTINUE).value = nil;
  453.   (ans->CONTINUE).target = nil;
  454.  
  455.   /*  (ans->CONTINUE).machine_state; */
  456.   (ans->CONTINUE).gc_stack_pointer = NULL;
  457.   (ans->CONTINUE).dynamic_env = NULL;
  458.   (ans->CONTINUE).last_continue = nil;
  459.   (ans->CONTINUE).handler_stack = nil;
  460.  
  461.   (ans->CONTINUE).dp = nil;
  462.  
  463.   (ans->CONTINUE).live = FALSE;
  464.   (ans->CONTINUE).unwind = FALSE;  
  465.   
  466.   return ans;
  467. }
  468.  
  469. LispObject allocate_stream(LispObject *stacktop, FILE *file, int mod)
  470. {
  471.   LispObject ans;
  472.  
  473.   ans = allocate_nbytes(stacktop,sizeof(struct stream_structure),TYPE_STREAM);
  474.  
  475.   lval_classof(ans) = Object;
  476.   (ans->STREAM).handle = file;
  477.   (ans->STREAM).name = nil; /* Wah? */
  478.   (ans->STREAM).mode = mod;
  479.   (ans->STREAM).curchar = 0;
  480.   return ans;
  481.  
  482. }
  483.  
  484. LispObject allocate_env(LispObject *stacktop, LispObject name, 
  485.             LispObject value, LispObject prev)
  486. {
  487.   LispObject ans;
  488.  
  489.   STACK_TMP(prev); STACK_TMP(name); STACK_TMP(value);
  490.   ans=allocate_nbytes(stacktop,sizeof(struct envobject),TYPE_ENV);
  491.   UNSTACK_TMP(value); UNSTACK_TMP(name); UNSTACK_TMP(prev);
  492.   lval_classof(ans) = nil; /* ? */
  493.  
  494.   ans->ENV.variable = name;
  495.   ans->ENV.value = value;
  496.   ans->ENV.next = &prev->ENV;
  497.   ans->ENV.mutable = lisptrue;
  498.  
  499.   return ans;
  500. }
  501.  
  502. LispObject allocate_envimut(LispObject *stacktop, LispObject name, LispObject value, LispObject prev)
  503. {
  504.   LispObject ans;
  505.   
  506.   ans=allocate_env(stacktop,name,value,prev);
  507.   
  508.   ans->ENV.mutable = nil;
  509.   return ans;
  510. }
  511.  
  512. LispObject allocate_special(LispObject *stacktop, 
  513.                 LispObject name, 
  514.                 LispObject (*fn)(LispObject *))
  515. {
  516.   LispObject ans;
  517.  
  518.   STACK_TMP(name);
  519.   ans=allocate_nbytes(stacktop,sizeof(struct special_structure),TYPE_SPECIAL);
  520.   UNSTACK_TMP(name);
  521.  
  522.   lval_classof(ans) = Object;
  523.  
  524.   ans->SPECIAL.name  = name;
  525.   ans->SPECIAL.env   = NULL;
  526.   ans->SPECIAL.func  = fn;
  527.  
  528.   return(ans);
  529.  
  530. }
  531.  
  532.  
  533. LispObject allocate_i_function(LispObject *stacktop, LispObject mod, 
  534.                    LispObject env, int argcode)
  535. {
  536.   LispObject ans;
  537.  
  538.   STACK_TMP(mod); STACK_TMP(env);
  539.   ans=allocate_nbytes(stacktop,sizeof(struct i_function_structure),TYPE_I_FUNCTION);
  540.  
  541.   UNSTACK_TMP(env); UNSTACK_TMP(mod);
  542.   lval_classof(ans)=Function;
  543.   ans->I_FUNCTION.name=nil;
  544.   ans->I_FUNCTION.home = mod;
  545.   ans->I_FUNCTION.env = &env->ENV;
  546.   ans->I_FUNCTION.argtype = argcode;
  547.   
  548.   ans->I_FUNCTION.bvl = nil;
  549.   ans->I_FUNCTION.body = nil;
  550.  
  551.   return ans;
  552. }
  553.  
  554.  
  555. LispObject allocate_i_module(LispObject *stacktop, LispObject name)
  556. {
  557.   LispObject ans;
  558.   LispObject tmp1,tmp2;
  559.   
  560.   STACK_TMP(name);
  561.   tmp1 = (LispObject) allocate_table(stacktop, Fn_eq);
  562.   STACK_TMP(tmp1);
  563.   tmp2 = (LispObject) allocate_table(stacktop, Fn_eq);    
  564.   STACK_TMP(tmp2);
  565.   ans=allocate_nbytes(stacktop,sizeof(struct i_module_structure), TYPE_I_MODULE);
  566.   UNSTACK_TMP(tmp2);
  567.   UNSTACK_TMP(tmp1);
  568.   UNSTACK_TMP(name);
  569.   lval_classof(ans)=Object;
  570.   ans->I_MODULE.name = name;
  571.   ans->I_MODULE.home = nil;
  572.   ans->I_MODULE.exported_names = nil;
  573.   ans->I_MODULE.bounce_flag = FALSE;
  574.   ans->I_MODULE.imported_modules = nil; /* HACK !!! GC */
  575.   ans->I_MODULE.bindings = tmp2;
  576.   
  577.   return ans;
  578. }
  579.  
  580. #if (defined(WITH_BSD_SOCKETS) || defined(WITH_SYSTEMV_SOCKETS))
  581.  
  582. LispObject allocate_listener(LispObject *stacktop)
  583. {
  584.   LispObject ans;
  585.  
  586.   ans=allocate_nbytes(stacktop,sizeof(struct listener_structure), TYPE_LISTENER);
  587.   lval_classof(ans)=nil; /* will be set later */
  588.   return ans;
  589. }
  590.  
  591.  
  592. LispObject allocate_socket(LispObject *stacktop)
  593. {
  594.   LispObject ans;
  595.   
  596.   ans=allocate_nbytes(stacktop,sizeof(struct socket_structure), TYPE_SOCKET);
  597.   lval_classof(ans)=nil; /* will be set later */
  598.   return ans;
  599. }
  600. #endif
  601.  
  602. LispObject allocate_semaphore(LispObject *stacktop)
  603. {
  604.   LispObject ans;
  605.   
  606.   ans=allocate_nbytes(stacktop,sizeof(struct semaphore_structure), TYPE_SEMAPHORE);
  607.  
  608.   lval_classof(ans)=Object; /* Ugh */
  609.   system_allocate_semaphore(&(ans->SEMAPHORE.semaphore));
  610.  
  611.   return ans;
  612. }
  613.  
  614. LispObject allocate_static_vector(LispObject *stacktop,int nslots)
  615. {
  616.   LispObject space;
  617.   int i;
  618.  
  619.   space=(LispObject) allocate_space(stacktop,sizeof(Object_t)+sizeof(int)+nslots*sizeof(LispObject));
  620.   
  621.   for (i=0; i<nslots; i++)
  622.     vref(space,i)=NULL;
  623.  
  624.   lval_typeof(space)=TYPE_VECTOR|STATIC_TYPE;
  625.   lval_classof(space)=Vector;
  626.   gcof(space)=current_space();
  627.   space->VECTOR.length=nslots;
  628.  
  629.   return(space);
  630. }
  631.  
  632. /* These are never called */
  633. void deallocate_page(LispObject *stacktop, char *addr, int n)
  634. {
  635.   
  636. }
  637.  
  638. LispObject show_free_heap(LispObject *stacktop)
  639. {
  640.  
  641. }
  642.  
  643. LispObject show_free_space(LispObject *stacktop)
  644. {
  645.  
  646. }
  647.  
  648. void promote_free_space(LispObject *stacktop)
  649. {
  650.  
  651. }
  652.  
  653.  
  654. void allocate_static_integers(LispObject *stacktop)
  655. {
  656. #ifdef NOLOWTAGINTS
  657.   int i;
  658.  
  659.   static_ints=allocate_static_vector(stacktop,STATIC_INTEGERS);
  660.   for (i=0; i<STATIC_INTEGERS; i++)
  661.     {        /* alloc a big integer, then 'fix' it */
  662.       LispObject xx=real_allocate_integer(stacktop,STATIC_INTEGERS);
  663.       intval(xx)=i;
  664.       vref(static_ints,i)=xx;
  665.     }
  666.  
  667.   add_root(&static_ints);
  668. #endif
  669. }
  670.  
  671.  
  672. typedef struct free_list_struct
  673. {
  674.   int size;
  675.   struct free_list_struct *next;
  676. } *FreeList;
  677.  
  678. static SYSTEM_GLOBAL(FreeList, stack_chain);
  679.  
  680. static int free_count;
  681. static int nfrags;
  682.  
  683. void initialise_stack_space(int stackspace)
  684. {
  685.   char *space=system_malloc(stackspace);
  686.   
  687.   SYSTEM_INITIALISE_GLOBAL(FreeList,stack_chain,NULL);
  688.   SYSTEM_GLOBAL_VALUE(stack_chain) = (FreeList) space;
  689.   
  690.   SYSTEM_GLOBAL_VALUE(stack_chain)->size= stackspace - sizeof(*SYSTEM_GLOBAL_VALUE(stack_chain));
  691.   SYSTEM_GLOBAL_VALUE(stack_chain)->next= NULL;
  692.   free_count=SYSTEM_GLOBAL_VALUE(stack_chain)->size;
  693.   nfrags=1;
  694. }
  695.  
  696. void show_stack_space()
  697. {
  698.   fprintf(stderr,"Stack space: %d remaining, %d fragments\n",free_count, nfrags);
  699. }
  700.  
  701. /* use header as pointer to prevously allocated stack */
  702.  
  703. char* allocate_stack(LispObject *stacktop, int nbytes)
  704. {
  705.   FreeList oldstack;
  706.   FreeList *walker;
  707.   char *ret;
  708.  
  709.   if (nbytes==0)
  710.     return NULL;
  711.  
  712.   system_open_semaphore(stacktop,&S_G_V(GC_sem)); 
  713.   walker= &SYSTEM_GLOBAL_VALUE(stack_chain);
  714.   nbytes=ROUND_ADDR(nbytes);
  715.  
  716.   free_count -= nbytes;
  717.  
  718.   while ( (*walker)!=NULL)
  719.     {
  720.       if ((*walker)->size+sizeof(*walker)==nbytes)
  721.     { 
  722.       ret= (char*) (*walker);
  723.       *walker=(*walker)->next;
  724.       nfrags--;
  725.       FPRINTF_GC_BUG((stderr,"{Cool stack: %x->%x}",ret,ret+nbytes));
  726.       GC_BUG(memset(ret,'S',nbytes));
  727.       system_close_semaphore(&S_G_V(GC_sem)); 
  728.       return ret;
  729.     }
  730.       if ((*walker)->size<nbytes)
  731.     {
  732.       FPRINTF_GC_BUG((stderr,"[Looking at: %x->%x (%d)]",*walker,(*walker)+(*walker)->size,
  733.               (*walker)->size));      
  734.       walker = &((*walker)->next);
  735.     }
  736.       else
  737.     {
  738.       ret= ((char *)((*walker)+1))+((*walker)->size-nbytes);
  739.       (*walker)->size=(*walker)->size-nbytes;
  740.       GC_BUG(memset(ret,'S',nbytes));
  741.       FPRINTF_GC_BUG((stderr,"{Alloc stack: %x->%x}",ret,ret+nbytes));
  742.       system_close_semaphore(&S_G_V(GC_sem)); 
  743.       return ret;
  744.     }
  745.     }
  746.   fprintf(stderr,"alloc stack: stack wimped out (%d remaining --- probably)\n",free_count);
  747.   system_close_semaphore(&S_G_V(GC_sem)); 
  748.   return NULL;
  749. }
  750.  
  751. void deallocate_stack(LispObject *stacktop, char *addr,int nbytes)
  752. {
  753.   FreeList old, walker;
  754.   /* Too damm lazy */
  755.   nbytes=ROUND_ADDR(nbytes);
  756.  
  757.   
  758.   system_open_semaphore(stacktop,&S_G_V(GC_sem)); 
  759.   walker=SYSTEM_GLOBAL_VALUE(stack_chain);
  760.   FPRINTF_GC_BUG((stderr,"{dealloc: %x->%x [%d]",addr,addr+nbytes,nbytes));
  761.   while (   ((char *)walker->next) < addr
  762.      && walker->next!=NULL)
  763.     {
  764.       /* sanity check */
  765.       if (walker >= walker->next)
  766.     { 
  767.       FPRINTF_GC_BUG((stderr,"Rats--- strange chain\n"));
  768.       system_lisp_exit(1);
  769.     }
  770.       walker=walker->next;
  771.     }
  772.   /* 3 cases --- at the start */
  773.   if ( ((char *)(walker+1)) + walker->size == addr)
  774.     {
  775.       /* side check for end */
  776.  
  777.       if (walker->next!=NULL && addr+nbytes == (char *) walker->next)
  778.     {
  779.       walker->size = walker->size+nbytes
  780.         +sizeof(*walker)
  781.           +walker->next->size;
  782.       walker->next=walker->next->next;
  783.       free_count+=nbytes+sizeof(*walker);
  784.       nfrags--;
  785.       FPRINTF_GC_BUG((stderr,"Filler}"));
  786.     }
  787.       else    
  788.     {
  789.       walker->size=walker->size+nbytes;
  790.       free_count+=nbytes;
  791.       FPRINTF_GC_BUG((stderr,"Start}"));
  792.     }
  793.       system_close_semaphore(&S_G_V(GC_sem)); 
  794.       return;
  795.     }
  796.   /* at the end */
  797.   if ( walker->next!=NULL && addr+nbytes == (char *) walker->next)
  798.     {
  799.       old=walker->next;
  800.       walker->next=(FreeList) addr;
  801.       walker->next->size=nbytes+old->size;
  802.       walker->next->next=old->next;
  803.       free_count+=nbytes;
  804.       FPRINTF_GC_BUG((stderr,"End}"));
  805.       system_close_semaphore(&S_G_V(GC_sem)); 
  806.       return;
  807.     }
  808.   /* in the middle */
  809.   old=walker->next;      
  810.   walker->next=(FreeList) addr;
  811.   walker->next->next=old;
  812.   walker->next->size=nbytes-sizeof(*walker);
  813.   nfrags++;
  814.   free_count+=nbytes-sizeof(*walker);
  815.   FPRINTF_GC_BUG((stderr,"Middle}"));
  816.   system_close_semaphore(&S_G_V(GC_sem)); 
  817. }
  818.   
  819. int dump_obj(unsigned int *x,int s)
  820. {
  821.   int i;
  822.   
  823.   if (s>200) s=16;
  824.  
  825.   for (i=0; i<s ; i+=4)
  826.     fprintf(stderr,"0x%x: %x %x %x %x\n",
  827.         x+i,
  828.         (int)*(x+i),(int)*(x+i+1),(int)*(x+i+2),(int)*(x+i+3));
  829.   return s;
  830. }
  831.   
  832.  
  833.  
  834.  
  835.  
  836.